# import modules.consensus.PoW as pw
import importlib
import inspect
import os
import gc
import globalVariables as gv
from modules.entities.node import Node
from utils.config_loader import config_loader, function_loader


class Blockchain:
    # 在初始化类的过程中，从配置文件确定加载哪些类方法，
    module_dict = config_loader("./config/globalConfig.json", "modules")

    # 用function_loader加载对应的方法
    for k, v in module_dict.items():
        module_name, function_name = v.split(" || ")
        locals()[k] = function_loader(module_name, function_name)

    # 分别加载对应模块的方法作为区块链加载的方法

    def __init__(self):
        # 单一区块内当前内容
        # TODO: 在后续的C++版本中，这里肯定要注意其大小，最好是固定的以优化存储空间的占用
        self.records = []
        # 记录包括自己在内的所有节点，以期能够从这些节点同步数据，同时也将自己收到的消息向这些节点转发
        self.node_id = os.urandom(16)  # 128 bits
        # 这里的节点更多表示其它邻居，但是目前靠手动添加,形式是modules.entities.node.py里面的Node
        self.nodes = []
        self.chain = []
        self.create_block(0, '00')

    def __str__(self):
        # 这里还应该有根据加载模块的不同而打印的消息。
        return str("节点id:" + self.node_id + "\t当前链长度:" + str(len(self.chain)) + "\n")\
                   + str("相邻节点信息: ") + str([self.nodes[i].node_address for i in range(len(self.nodes))])

    # 回收一些杂数据，省的之后的代码生乱
    del module_dict; del module_name; del function_name; del k; del v;
    gc.collect()


if __name__ == '__main__':
    b = Blockchain()
    print(b)
    print(os.path.abspath(__file__))
